#include <algorithm>
#include <iostream>
#include <string>
#include "plc2llvm/Visitor/strategy/expression/expression.h"
#include "plc2llvm/utils/Log.h"
#include "plc2llvm/utils/Utils.h"
#include "plc2llvm/TypeSystem/Basic/BasicInclude.h"
#include "plc2llvm/TypeSystem/TypeMachine.h"
#include "plc2llvm/Semantic/SemanticError.h"
#include "plc2llvm/Semantic/SemanticWarning.h"
#include "plc2llvm/ScopeSystem/ScopeManager.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Type.h"

#define ANY_CAST_TO_OBJ(x) std::any_cast<std::shared_ptr<plcst::Object>>(x)

namespace expression
{

    /*
        访问子节点，获得PLCExpr*，检查是否为常量，不是常量则报错
    */
    std::any visitConstant_Expr(plcst::PLCSTParser::Constant_ExprContext *ctx, Visitor *visitor)
    {
        auto raw_expr = visitor->visit(ctx->expression());
        auto expr = ANY_CAST_TO_OBJ(raw_expr);
        if (!expr->getIsConst())
        {
            throw SemanticError(visitor->getTokenStream(), ctx, "expresson is not constant.");
        }
        return raw_expr;
    }

    /*
        访问子节点xor_Expr，构建expression树
    */
    std::any visitExpression(plcst::PLCSTParser::ExpressionContext *ctx, Visitor *visitor)
    {
        // 只有一个节点
        auto first_expr_obj = visitor->visit(ctx->xor_Expr(0));
        if (ctx->children.size() == 1)
        {
            return first_expr_obj;
        }
        // get expr_0
        auto expr_obj = ANY_CAST_TO_OBJ(first_expr_obj);
        // get type
        auto expr_ty = expr_obj->getType();
        // get value
        auto value = expr_obj->llvmval;
        // process rest
        for (int i = 1; i <= ctx->xor_Expr().size() - 1; i++)
        {
            // 获取another obj and type
            auto raw_another = visitor->visit(ctx->xor_Expr(i));
            auto another = ANY_CAST_TO_OBJ(raw_another);
            auto anotherType = another->getType();
            // get op (this (->)op(<-) another op ....)
            auto opstr = ctx->children.at(2 * i - 1)->getText();
            plcst::ExpressionOperator op;
            if (opstr == "OR")
            {
                op = plcst::ExpressionOperator::OR;
            }
            else
            {
                throw SemanticError(visitor->getTokenStream(), ctx->xor_Expr(i), "unknow operator: " + opstr);
            }
            // get res type
            auto res = expr_ty->typeSynthesisForBinaryOperator(op, anotherType);
            switch (res.signal)
            {
            case 1:
                // TODO: warnning info
            case 0:
            {
                // codegen TODO
                auto leftval = expr_ty->castTo(res.t, value, visitor->builder);
                auto rightval = anotherType->castTo(res.t, another->llvmval, visitor->builder);
                switch (op)
                {
                case plcst::ExpressionOperator::EQUAL:
                    value = value;
                    break;
                case plcst::ExpressionOperator::NOTEQUAL:
                {
                    value = value;
                    break;
                }
                }
                expr_ty = res.t;
                break;
            }
            case 2:
                throw SemanticError(visitor->getTokenStream(), ctx, "Illegal expression operation" + opstr);
                break;
            default:
                throw SemanticError(visitor->getTokenStream(), ctx, "unknow error");
            }
        }
        // flash type of obj
        expr_obj->setType(expr_ty);
        expr_obj->llvmval = value;
        return expr_obj;
    }

    /*
        分析方法同expression
    */
    std::any visitXor_Expr(plcst::PLCSTParser::Xor_ExprContext *ctx, Visitor *visitor)
    {
        // 只有一个节点
        auto first_expr_obj = visitor->visit(ctx->and_Expr(0));
        if (ctx->children.size() == 1)
        {
            return first_expr_obj;
        }
        // get expr_0
        auto expr_obj = ANY_CAST_TO_OBJ(first_expr_obj);
        // get type
        auto expr_ty = expr_obj->getType();
        // get value
        auto value = expr_obj->llvmval;
        // process rest
        for (int i = 1; i <= ctx->and_Expr().size() - 1; i++)
        {
            // 获取another obj and type
            auto raw_another = visitor->visit(ctx->and_Expr(i));
            auto another = ANY_CAST_TO_OBJ(raw_another);
            auto anotherType = another->getType();
            // get op (this (->)op(<-) another op ....)
            auto opstr = ctx->children.at(2 * i - 1)->getText();
            plcst::ExpressionOperator op;
            if (opstr == "XOR")
            {
                op = plcst::ExpressionOperator::XOR;
            }
            else
            {
                throw SemanticError(visitor->getTokenStream(), ctx->and_Expr(i), "unknow operator: " + opstr);
            }
            // get res type
            auto res = expr_ty->typeSynthesisForBinaryOperator(op, anotherType);
            switch (res.signal)
            {
            case 1:
                // TODO: warnning info
            case 0:
            {
                // codegen TODO
                auto leftval = expr_ty->castTo(res.t, value, visitor->builder);
                auto rightval = anotherType->castTo(res.t, another->llvmval, visitor->builder);
                switch (op)
                {
                case plcst::ExpressionOperator::EQUAL:
                    value = value;
                    break;
                case plcst::ExpressionOperator::NOTEQUAL:
                {
                    value = value;
                    break;
                }
                }
                expr_ty = res.t;
                break;
            }
            case 2:
                throw SemanticError(visitor->getTokenStream(), ctx, "Illegal expression operation" + opstr);
                break;
            default:
                throw SemanticError(visitor->getTokenStream(), ctx, "unknow error");
            }
        }
        // flash type of obj
        expr_obj->setType(expr_ty);
        expr_obj->llvmval = value;
        return expr_obj;
    }

    std::any visitAnd_Expr(plcst::PLCSTParser::And_ExprContext *ctx, Visitor *visitor)
    {
        // 只有一个节点
        auto first_expr_obj = visitor->visit(ctx->compare_Expr(0));
        if (ctx->children.size() == 1)
        {
            return first_expr_obj;
        }
        // get expr_0
        auto expr_obj = ANY_CAST_TO_OBJ(first_expr_obj);
        // get type
        auto expr_ty = expr_obj->getType();
        // get value
        auto value = expr_obj->llvmval;
        // process rest
        for (int i = 1; i <= ctx->compare_Expr().size() - 1; i++)
        {
            // 获取another obj and type
            auto raw_another = visitor->visit(ctx->compare_Expr(i));
            auto another = ANY_CAST_TO_OBJ(raw_another);
            auto anotherType = another->getType();
            // get op (this (->)op(<-) another op ....)
            auto opstr = ctx->children.at(2 * i - 1)->getText();
            plcst::ExpressionOperator op;
            if (opstr == "&" || opstr == "AND")
            {
                op = plcst::ExpressionOperator::AND;
            }
            else
            {
                throw SemanticError(visitor->getTokenStream(), ctx->compare_Expr(i), "unknow operator: " + opstr);
            }
            // get res type
            auto res = expr_ty->typeSynthesisForBinaryOperator(op, anotherType);
            switch (res.signal)
            {
            case 1:
                // TODO: warnning info
            case 0:
            {
                // codegen TODO
                auto leftval = expr_ty->castTo(res.t, value, visitor->builder);
                auto rightval = anotherType->castTo(res.t, another->llvmval, visitor->builder);
                switch (op)
                {
                case plcst::ExpressionOperator::EQUAL:
                    value = value;
                    break;
                case plcst::ExpressionOperator::NOTEQUAL:
                {
                    value = value;
                    break;
                }
                }
                expr_ty = res.t;
                break;
            }
            case 2:
                throw SemanticError(visitor->getTokenStream(), ctx, "Illegal expression operation" + opstr);
                break;
            default:
                throw SemanticError(visitor->getTokenStream(), ctx, "unknow error");
            }
        }
        // flash type of obj
        expr_obj->setType(expr_ty);
        expr_obj->llvmval = value;
        return expr_obj;
    }

    std::any visitCompare_Expr(plcst::PLCSTParser::Compare_ExprContext *ctx, Visitor *visitor)
    {
        // 只有一个节点
        auto first_expr_obj = visitor->visit(ctx->equ_Expr(0));
        if (ctx->children.size() == 1)
        {
            return first_expr_obj;
        }
        // get expr_0
        auto expr_obj = ANY_CAST_TO_OBJ(first_expr_obj);
        // get type
        auto expr_ty = expr_obj->getType();
        // get value
        auto value = expr_obj->llvmval;
        // process rest
        for (int i = 1; i <= ctx->equ_Expr().size() - 1; i++)
        {
            // 获取another obj and type
            auto raw_another = visitor->visit(ctx->equ_Expr(i));
            auto another = ANY_CAST_TO_OBJ(raw_another);
            auto anotherType = another->getType();
            // get op (this (->)op(<-) another op ....)
            auto opstr = ctx->children.at(2 * i - 1)->getText();
            plcst::ExpressionOperator op;
            if (opstr == "=")
            {
                op = plcst::ExpressionOperator::EQUAL;
            }
            else if (opstr == "<>")
            {
                op = plcst::ExpressionOperator::NOTEQUAL;
            }
            else
            {
                throw SemanticError(visitor->getTokenStream(), ctx->equ_Expr(i), "unknow operator: " + opstr);
            }
            // get res type
            auto res = expr_ty->typeSynthesisForBinaryOperator(op, anotherType);
            switch (res.signal)
            {
            case 1:
                // TODO: warnning info
            case 0:
            {
                // codegen TODO
                auto leftval = expr_ty->castTo(res.t, value, visitor->builder);
                auto rightval = anotherType->castTo(res.t, another->llvmval, visitor->builder);
                switch (op)
                {
                case plcst::ExpressionOperator::EQUAL:
                    value = value;
                    break;
                case plcst::ExpressionOperator::NOTEQUAL:
                {
                    value = value;
                    break;
                }
                }
                expr_ty = res.t;
                break;
            }

            case 2:
                throw SemanticError(visitor->getTokenStream(), ctx, "Illegal expression operation" + opstr);
                break;
            default:
                throw SemanticError(visitor->getTokenStream(), ctx, "unknow error");
            }
        }
        // flash type of obj
        expr_obj->setType(expr_ty);
        expr_obj->llvmval = value;
        return expr_obj;
    }

    std::any visitEqu_Expr(plcst::PLCSTParser::Equ_ExprContext *ctx, Visitor *visitor)
    {
        // 只有一个节点
        auto first_expr_obj = visitor->visit(ctx->add_Expr(0));
        if (ctx->children.size() == 1)
        {
            return first_expr_obj;
        }
        // get expr_0
        auto expr_obj = ANY_CAST_TO_OBJ(first_expr_obj);
        // get type
        auto expr_ty = expr_obj->getType();
        // get type
        auto value = expr_obj->llvmval;
        // process rest
        for (int i = 1; i <= ctx->add_Expr().size() - 1; i++)
        {
            // 获取another obj and type
            auto raw_another = visitor->visit(ctx->add_Expr(i));
            auto another = ANY_CAST_TO_OBJ(raw_another);
            auto anotherType = another->getType();
            // get op (this (->)op(<-) another op ....)
            auto opstr = ctx->children.at(2 * i - 1)->getText();
            plcst::ExpressionOperator op;
            if (opstr == "<")
            {
                op = plcst::ExpressionOperator::LESS;
            }
            else if (opstr == ">")
            {
                op = plcst::ExpressionOperator::GREATER;
            }
            else if (opstr == "<=")
            {
                op = plcst::ExpressionOperator::LESSEQUAL;
            }
            else if (opstr == ">=")
            {
                op = plcst::ExpressionOperator::GREATEREQUAL;
            }
            else
            {
                throw SemanticError(visitor->getTokenStream(), ctx->add_Expr(i), "unknow operator: " + opstr);
            }
            // get res type
            auto res = expr_ty->typeSynthesisForBinaryOperator(op, anotherType);
            switch (res.signal)
            {
            case 1:
                // TODO: warnning info
            case 0:
            {
                // codegen TODO
                auto leftval = expr_ty->castTo(res.t, value, visitor->builder);
                auto rightval = anotherType->castTo(res.t, another->llvmval, visitor->builder);
                switch (op)
                {
                case plcst::ExpressionOperator::LESS:
                    value = value;
                    break;
                case plcst::ExpressionOperator::GREATER:
                {
                    value = value;
                    break;
                }
                case plcst::ExpressionOperator::LESSEQUAL:
                {
                    value = value;
                    break;
                }
                case plcst::ExpressionOperator::GREATEREQUAL:
                {
                    value = value;
                    break;
                }
                }
                expr_ty = res.t;
                break;
            }

            case 2:
                throw SemanticError(visitor->getTokenStream(), ctx, "Illegal expression operation" + opstr);
                break;
            default:
                throw SemanticError(visitor->getTokenStream(), ctx, "unknow error");
            }
        }
        // flash type of obj
        expr_obj->setType(expr_ty);
        expr_obj->llvmval = value;
        return expr_obj;
    }

    // push llvm::value
    std::any visitAdd_Expr(plcst::PLCSTParser::Add_ExprContext *ctx, Visitor *visitor)
    {
        // 只有一个节点
        auto raw_add_expr_obj = visitor->visit(ctx->term(0));
        if (ctx->children.size() == 1)
        {
            return raw_add_expr_obj;
        }
        // get term_0
        auto add_expr_obj = ANY_CAST_TO_OBJ(raw_add_expr_obj);
        // get type
        auto add_expr_ty = add_expr_obj->getType();
        // get value
        auto value = add_expr_obj->llvmval;
        // process rest
        for (int i = 1; i <= ctx->term().size() - 1; i++)
        {
            // 获取another obj and type
            auto raw_another = visitor->visit(ctx->term(i));
            auto another = ANY_CAST_TO_OBJ(raw_another);
            auto anotherType = another->getType();
            // get op (this (->)op(<-) another op ....)
            auto opstr = ctx->children.at(2 * i - 1)->getText();
            plcst::ExpressionOperator op;
            if (opstr == "+")
            {
                op = plcst::ExpressionOperator::ADD;
            }
            else if (opstr == "-")
            {
                op = plcst::ExpressionOperator::MINUS;
            }
            else
            {
                throw SemanticError(visitor->getTokenStream(), ctx->term(i), "unknow operator: " + opstr);
            }
            // get res type
            auto res = add_expr_ty->typeSynthesisForBinaryOperator(op, anotherType);
            switch (res.signal)
            {
            case 1:
                // TODO: warnning info
            case 0:
            {
                // codegen
                auto leftval = add_expr_ty->castTo(res.t, value, visitor->builder);
                auto rightval = anotherType->castTo(res.t, another->llvmval, visitor->builder);
                switch (op)
                {
                case plcst::ExpressionOperator::ADD:
                {
                    value = visitor->builder->CreateAdd(leftval, rightval);
                    break;
                }
                case plcst::ExpressionOperator::MINUS:
                {
                    value = visitor->builder->CreateSub(leftval, rightval);
                    break;
                }
                }
                add_expr_ty = res.t;
                break;
            }
            case 2:
                throw SemanticError(visitor->getTokenStream(), ctx, "Illegal expression operation" + opstr);
                break;
            default:
                throw SemanticError(visitor->getTokenStream(), ctx, "unknow error");
            }
        }
        // flash type of obj
        add_expr_obj->setType(add_expr_ty);
        add_expr_obj->llvmval = value;
        return add_expr_obj;
    }

    std::any visitTerm(plcst::PLCSTParser::TermContext *ctx, Visitor *visitor)
    {
        // 只有一个节点
        auto first_expr_obj = visitor->visit(ctx->power_Expr(0));
        if (ctx->children.size() == 1)
        {
            return first_expr_obj;
        }
        // get expr_0
        auto expr_obj = ANY_CAST_TO_OBJ(first_expr_obj);
        // get type
        auto expr_ty = expr_obj->getType();
        // get value
        auto value = expr_obj->llvmval;
        // process rest
        for (int i = 1; i <= ctx->power_Expr().size() - 1; i++)
        {
            // 获取another obj and type
            auto raw_another = visitor->visit(ctx->power_Expr(i));
            auto another = ANY_CAST_TO_OBJ(raw_another);
            auto anotherType = another->getType();
            // get op (this (->)op(<-) another op ....)
            auto opstr = ctx->children.at(2 * i - 1)->getText();
            plcst::ExpressionOperator op;
            if (opstr == "*")
            {
                op = plcst::ExpressionOperator::MULTI;
            }
            else if (opstr == "/")
            {
                op = plcst::ExpressionOperator::DIV;
            }
            else if (opstr == "MOD")
            {
                op = plcst::ExpressionOperator::MOD;
            }
            else
            {
                throw SemanticError(visitor->getTokenStream(), ctx->power_Expr(i), "unknow operator: " + opstr);
            }
            // get res type
            auto res = expr_ty->typeSynthesisForBinaryOperator(op, anotherType);
            switch (res.signal)
            {
            case 1:
                // TODO: warnning info
            case 0:
            {
                // codegen
                auto leftval = expr_ty->castTo(res.t, value, visitor->builder);
                auto rightval = anotherType->castTo(res.t, another->llvmval, visitor->builder);
                auto destTypeKind = res.t->getTypeKind();
                auto tm = plcst::TypeMachine::getTypeMachine();
                switch (op)
                {
                case plcst::ExpressionOperator::MULTI:
                    value = visitor->builder->CreateMul(leftval, rightval);
                    break;
                case plcst::ExpressionOperator::DIV:
                {
                    if (tm.isUnsignedInt(destTypeKind))
                    {
                        value = visitor->builder->CreateUDiv(leftval, rightval);
                    }
                    else if (tm.isSignedInt(destTypeKind))
                    {
                        value = visitor->builder->CreateSDiv(leftval, rightval);
                    }
                    else if (tm.isReal(destTypeKind))
                    {
                        value = visitor->builder->CreateFDiv(leftval, rightval);
                    }
                }
                case plcst::ExpressionOperator::MOD:
                {
                    value = value; // TODO: cannot find llvm mod instr
                }
                }
                expr_ty = res.t;
                break;
            }
            case 2:
                throw SemanticError(visitor->getTokenStream(), ctx, "Illegal expression operation" + opstr);
                break;
            default:
                throw SemanticError(visitor->getTokenStream(), ctx, "unknow error");
            }
        }
        // flash type of obj
        expr_obj->setType(expr_ty);
        expr_obj->llvmval = value;
        return expr_obj;
    }

    std::any visitPower_Expr(plcst::PLCSTParser::Power_ExprContext *ctx, Visitor *visitor)
    {
        // 只有一个节点
        auto first_expr_obj = visitor->visit(ctx->unary_Expr(0));
        if (ctx->children.size() == 1)
        {
            return first_expr_obj;
        }
        // get expr_0
        auto expr_obj = ANY_CAST_TO_OBJ(first_expr_obj);
        // get type
        auto expr_ty = expr_obj->getType();
        // get llvm value
        auto value = expr_obj->llvmval;
        // process rest
        for (int i = 1; i <= ctx->unary_Expr().size() - 1; i++)
        {
            // 获取another obj and type
            auto raw_another = visitor->visit(ctx->unary_Expr(i));
            auto another = ANY_CAST_TO_OBJ(raw_another);
            auto anotherType = another->getType();
            // get op (this (->)op(<-) another op ....)
            auto opstr = ctx->children.at(2 * i - 1)->getText();
            plcst::ExpressionOperator op;
            if (opstr == "**")
            {
                op = plcst::ExpressionOperator::POWER;
            }
            else
            {
                throw SemanticError(visitor->getTokenStream(), ctx->unary_Expr(i), "unknow operator: " + opstr);
            }
            // get res type
            auto res = expr_ty->typeSynthesisForBinaryOperator(op, anotherType);
            switch (res.signal)
            {
            case 1:
                // TODO: warnning info
            case 0:
            {
                // codegen
                auto leftval = expr_ty->castTo(res.t, value, visitor->builder);
                auto rightval = anotherType->castTo(res.t, another->llvmval, visitor->builder);
                // TODO: cannot find llvm pow function
                value = visitor->builder->CreateMul(leftval, rightval);
                expr_ty = res.t;
                break;
            }
            case 2:
                throw SemanticError(visitor->getTokenStream(), ctx, "Illegal expression operation" + opstr);
                break;
            default:
                throw SemanticError(visitor->getTokenStream(), ctx, "unknow error");
            }
        }
        // flash type and llvmvalue of obj
        expr_obj->setType(expr_ty);
        expr_obj->llvmval = value;
        return expr_obj;
    }

    std::any visitUnary_Expr(plcst::PLCSTParser::Unary_ExprContext *ctx, Visitor *visitor)
    {
        auto raw_primary_expr = visitor->visit(ctx->primary_Expr());
        if (ctx->children.size() == 1)
        { // 没有Minus | Plus | NOT
            return raw_primary_expr;
        }
        else
        {
            auto obj = std::any_cast<std::shared_ptr<plcst::Object>>(raw_primary_expr);
            auto objType = obj->getType();
            auto opstr = ctx->children.at(0)->getText();
            plcst::ExpressionOperator op;

            if (opstr == "+")
            {
                op = plcst::ExpressionOperator::POSITIVE;
            }
            else if (opstr == "-")
            {
                op = plcst::ExpressionOperator::NEGATIVE;
            }
            else
            {
                op = plcst::ExpressionOperator::NOT;
            }
            auto newTy = objType->typeSynthesisForUnaryOperator(op);
            // codegen obj llvm value
            auto llvmValue = obj->llvmval;
            switch (newTy.signal)
            {
            case 1:
                // codegen
                switch (op)
                {
                case plcst::ExpressionOperator::NEGATIVE:
                {
                    obj->llvmval = visitor->builder->CreateNeg(llvmValue);
                }
                case plcst::ExpressionOperator::NOT:
                {
                    obj->llvmval = visitor->builder->CreateNot(llvmValue);
                }
                }
                return obj;
            case 2: // TODO: add warnning
                obj->llvmval = obj->getType()->castTo(newTy.t, obj->llvmval, visitor->builder);
                obj->setType(newTy.t);
                // codegen
                switch (op)
                {
                case plcst::ExpressionOperator::NEGATIVE:
                {
                    obj->llvmval = visitor->builder->CreateNeg(llvmValue);
                }
                case plcst::ExpressionOperator::NOT:
                {
                    obj->llvmval = visitor->builder->CreateNot(llvmValue);
                }
                }
                return obj;
            case 3:
                throw SemanticError(visitor->getTokenStream(), ctx, "error usage of " + opstr);
            }
            return nullptr;
        }
    }

    std::any visitPrimary_Expr(plcst::PLCSTParser::Primary_ExprContext *ctx, Visitor *visitor)
    {
        if (ctx->identifier() != nullptr)
        {
            // find obj and create a new obj
            auto objectname = ctx->identifier()->getText();
            auto raw_objectSymbol = plcst::ScopeManager::getScopeManager().find<plcst::Object>(objectname);
            auto obj = ANY_CAST_TO_OBJ(raw_objectSymbol);
            // get type info
            auto objType = obj->getType();
            // create obj
            auto tmpObj = std::make_shared<plcst::Object>(objType, "tmpId", true);
            // insert llvm value
            tmpObj->llvmval = visitor->builder->CreateLoad(objType->llvmty, obj->llvmval);
            return tmpObj;
        }

        return visitor->visitChildren(ctx);
    }

    std::any visitIdentifier(plcst::PLCSTParser::IdentifierContext *ctx, Visitor *visitor)
    {
        auto identifier = ctx->Identifier()->getText();
        return identifier;
    }

    std::any visitParen_Surrounded_Expr(plcst::PLCSTParser::Paren_Surrounded_ExprContext *ctx, Visitor *visitor)
    {
        return visitor->visit(ctx->expression());
    }

    std::any visitConstant(plcst::PLCSTParser::ConstantContext *ctx, Visitor *visitor)
    {
        return visitor->visitChildren(ctx);
    }

    // push value
    std::any visitInt_Literal(plcst::PLCSTParser::Int_LiteralContext *ctx, Visitor *visitor)
    {
        // 获取type
        std::string typeName;
        if (ctx->children.size() == 3)
        { // 指定了类型
            typeName = ctx->Int_Type_Name()->getText();
        }
        else
        {
            typeName = "INT";
        }

        // get type info
        auto objType = plcst::ScopeManager::getScopeManager().find<plcst::Type>(typeName);
        auto typeDetail = std::dynamic_pointer_cast<plcst::BasicType>(objType);
        bool ifSigned = plcst::TypeMachine::getTypeMachine().isSignedInt(typeDetail->getTypeKind());
        // get content and value
        std::string constStringContent = ctx->children.back()->getText();
        auto value = plcst::utils::intLiteralToNum(constStringContent);
        // create obj
        auto tmpObj = std::make_shared<plcst::Object>(objType, "tmpIntConst", true);
        // insert llvm value
        tmpObj->llvmval = llvm::ConstantInt::get(typeDetail->llvmty, value, ifSigned);
        return tmpObj;
    }

    std::any visitReal_Literal(plcst::PLCSTParser::Real_LiteralContext *ctx, Visitor *visitor)
    {
        // 获取type
        std::string typeName;
        if (ctx->children.size() == 3)
        { // 指定了类型
            auto typeName = ctx->Real_Type_Name()->getText();
        }
        else
        {
            typeName = "REAL";
        }

        auto objType = plcst::ScopeManager::getScopeManager().find<plcst::Type>(typeName);
        auto typeDetail = std::dynamic_pointer_cast<plcst::BasicType>(objType);
        // 获取content
        std::string constStringContent = ctx->children.back()->getText();
        auto value = plcst::utils::realLiteralToNum(constStringContent);
        auto tmpObj = std::make_shared<plcst::Object>(std::move(objType), "tmp", true);
        // tmpObj->llvmval = llvm::ConstantFP::get()
        // TODO:GET fp value
        return tmpObj;
    }

    std::any visitEnum_Value(plcst::PLCSTParser::Enum_ValueContext *ctx, Visitor *visitor)
    {
        return visitor->visitChildren(ctx);
    }

    std::any visitVariable_Access(plcst::PLCSTParser::Variable_AccessContext *ctx, Visitor *visitor)
    {
        return visitor->visitChildren(ctx);
    }

    std::any visitFunc_Call(plcst::PLCSTParser::Func_CallContext *ctx, Visitor *visitor)
    {
        return visitor->visitChildren(ctx);
    }

    std::any visitRef_Value(plcst::PLCSTParser::Ref_ValueContext *ctx, Visitor *visitor)
    {
        return visitor->visitChildren(ctx);
    }
}